<script setup lang="ts">
import type { Props } from './type.d'
// ------------------use------------------
// #region
const props = withDefaults(defineProps<Props>(), {
  value: true,
  offset: 20,
  position: 'left',
  target: () => document.body,
  color: 'var(--el-color-primary)',
  displayAnimation: false,
})
const emits = defineEmits(['update:value', 'change'])
// #endregion
// ------------------静态变量------------------
// #region

// #endregion
// ------------------动态变量------------------
// #region
let timer: any
let mouseTimer: any
// #endregion
// ------------------ref-----------
// #region
/** 控制隐藏与否 */
const isHide = ref<boolean>(true)
const bFoldRef = ref<HTMLElement>()
const isEnterTarget = ref<boolean>(false)
// #endregion
// ------------------reactive------
// #region

// #endregion
// ------------------computed------
// #region
const x = computed(
  () =>
    `${props.position === 'left' ? '-' : ''}${
      props.offset
    }px`,
)
// #endregion
// ------------------生命周期------------------
// #region
onMounted(async () => {
  await nextTick()
  bindEvent()
})
// #endregion
// ------------------内置方法---------------------
// #region

// #endregion
// ------------------方法---------------------
// #region
function bindEvent() {
  if (!props.displayAnimation)
    return

  const targetNode = props.target()

  if (!targetNode)
    return
  targetNode.addEventListener('mouseenter', () => {
    isEnterTarget.value = true
    // clearTimeout(mouseTimer);
    timer = setTimeout(() => {
      isHide.value = true
    }, 200)
  })
  targetNode.addEventListener('mouseleave', () => {
    isEnterTarget.value = false
    isHide.value = false
  })
  bFoldRef.value?.addEventListener('mouseenter', () => {
    clearTimeout(timer)
    clearTimeout(mouseTimer)
    isHide.value = false
  })
  window.addEventListener('mousemove', () => {
    if (isEnterTarget.value)
      return
    isHide.value = false
    clearTimeout(mouseTimer)
    mouseTimer = setTimeout(() => {
      isHide.value = true
    }, 2000)
  })
}
function handleClick() {
  emits('update:value', !props.value)
  emits('change', !props.value)
}
// #endregion
</script>

<template>
  <div
    ref="bFoldRef"
    class="b-fold"
    :class="[
      position === 'left'
        ? 'b-fold--left'
        : 'b-fold--right',
      value ? 'open' : 'close',
      {
        hide: isHide,
      },
    ]"
    @click="handleClick"
  >
    <span />
  </div>
</template>

<style lang="scss" scoped>
.b-fold {
  --b-fold-bgc: v-bind(color);
  --b-fold-x: v-bind(x);
  --b-fold-w: 6px;
  --b-fold-h: 60px;
  position: absolute;
  cursor: pointer;
  transition: all 0.3s var(--motion-bezier);
  margin-left: calc(0px - var(--b-fold-w));
  z-index: 99;
  &.hide {
    opacity: 0;
  }
  &::before,
  &::after {
    position: absolute;
    left: 0px;
    content: '';
    width: var(--b-fold-w);
    height: calc((var(--b-fold-h) + var(--b-fold-w)) / 2);
    background-color: var(--b-fold-bgc);
    border-radius: 9999px;
    transition: transform 0.3s var(--motion-bezier),
      filter 0.3s var(--motion-bezier);
  }
  &:hover {
    &::before,
    &::after {
      filter: brightness(1.2);
    }
  }
  &::before {
    top: 0px;
    transform: translateY(
      calc(-100% + var(--b-fold-w) / 2)
    );
  }
  &::after {
    bottom: 0px;
    transform: translateY(calc(100% - var(--b-fold-w) / 2));
  }
  &--left {
    left: 0px;
    &.open {
      &::before {
        transform-origin: center top;
      }
      &::after {
        transform-origin: center bottom;
      }
      &:hover::before {
        transform-origin: center top;
        transform: translateY(
            calc(-100% + var(--b-fold-w) / 2)
          )
          rotate(-20deg) scale(1.05);
      }
      &:hover::after {
        transform-origin: center bottom;
        transform: translateY(
            calc(100% - var(--b-fold-w) / 2)
          )
          rotate(20deg) scale(1.05);
      }
    }
    &.close {
      &::before {
        transform-origin: center bottom;
      }
      &::after {
        transform-origin: center top;
      }
      &:hover::before {
        transform-origin: center bottom;
        transform: translateY(
            calc(-100% + var(--b-fold-w) / 2)
          )
          rotate(20deg) scale(1.05);
      }
      &:hover::after {
        transform-origin: center top;
        transform: translateY(
            calc(100% - var(--b-fold-w) / 2)
          )
          rotate(-20deg) scale(1.05);
      }
    }
  }
  &--right {
    right: 0px;
    &.close {
      &::before {
        transform-origin: center bottom;
      }
      &::after {
        transform-origin: center top;
      }
      &:hover::before {
        transform-origin: center bottom;
        transform: translateY(
            calc(-100% + var(--b-fold-w) / 2)
          )
          rotate(-20deg) scale(1.05);
      }
      &:hover::after {
        transform-origin: center top;
        transform: translateY(
            calc(100% - var(--b-fold-w) / 2)
          )
          rotate(20deg) scale(1.05);
      }
    }
    &.open {
      &::before {
        transform-origin: center top;
      }
      &::after {
        transform-origin: center bottom;
      }
      &:hover::before {
        transform-origin: center top;
        transform: translateY(
            calc(-100% + var(--b-fold-w) / 2)
          )
          rotate(20deg);
      }
      &:hover::after {
        transform-origin: center bottom;
        transform: translateY(
            calc(100% - var(--b-fold-w) / 2)
          )
          rotate(-20deg);
      }
    }
  }
  &--left,
  &--right {
    top: 50%;
    transform: translateY(-50%) translateX(var(--b-fold-x));
  }

  /**扩大选中区域 */
  span {
    &::before,
    &::after {
      position: absolute;
      top: 0px;
      left: 0px;
      z-index: -1;
      transform: translateY(-50%) translateX(-50%);
      content: '';
      width: calc(var(--b-fold-w) * 4);
      height: var(--b-fold-h);
      background-color: transparent;
    }
  }
}
//------------------组件样式------------------
//-------------样式穿透-------------
</style>
